package com.octopus.properties;


import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.apache.log4j.Logger;

import com.octopus.string.StringUtils;


public class PropertiesUtils {
	
	private static Logger logger = Logger.getLogger(PropertiesUtils.class.getName());
	
	public static Properties loadFlatfileProperties(String fileName, String charset) throws PropertiesLoadFailedException{
		if(fileName == null || fileName.trim().length() == 0){
			throw new PropertiesLoadFailedException(StringUtils.concat("CommonUtil loadFlatfileProperties fileName is null [",fileName == null ? "NULL":"NULLSTRING","]"));
		}
		Properties properties = null;
		FileInputStream fis = null;
		try{
			fis = new FileInputStream(fileName);
			String content = StringUtils.inputStreamToRightString(fis, charset);
			properties = loadProperties(content);
		}catch(FileNotFoundException fnfe){
			throw new PropertiesLoadFailedException(StringUtils.concat("Could not get cofig file, please check whether the config file[",fileName,"] exists"),fnfe);
		}catch(IOException ioe){
			throw new PropertiesLoadFailedException(StringUtils.concat("When load config file, IOException occur[",ioe.getMessage(),"]"),ioe);
		}finally{
			try{
				if(fis != null){
					fis.close();
				}
			}catch(IOException ioe){
				logger.warn(StringUtils.concat("When to close the file InputStream[",fileName,"] inputStream"), ioe);
			}
		}
		return properties;
	}
	
	public static Properties loadFlatfileProperties(File file, String charset) throws PropertiesLoadFailedException{
		if(file == null || (!file.exists()) || (!file.isFile())){
			throw new PropertiesLoadFailedException(StringUtils.concat("CommonUtil loadFlatfileProperties File is null or not file[",file == null ? "NULL":file.getAbsolutePath(),"]"));
		}
		Properties properties = null;
		FileInputStream fis = null;
		try{
			fis = new FileInputStream(file);
			String content = StringUtils.inputStreamToRightString(fis, charset);
			properties = loadProperties(content);
		}catch(FileNotFoundException fnfe){
			throw new PropertiesLoadFailedException(StringUtils.concat("Could not get cofig file, please check whether the config file[",file.getAbsolutePath(),"] exists"),fnfe);
		}catch(IOException ioe){
			throw new PropertiesLoadFailedException(StringUtils.concat("When load config file, IOException occur[",ioe.getMessage(),"]"),ioe);
		}finally{
			try{
				if(fis != null){
					fis.close();
				}
			}catch(IOException ioe){
				logger.warn(StringUtils.concat("When to close the file InputStream[",file.getAbsolutePath(),"] inputStream"), ioe);
			}
		}
		return properties;
	}
	
	public static Properties loadProperties(InputStream is, String charset) throws PropertiesLoadFailedException{
		if(is == null){
			throw new PropertiesLoadFailedException("InputStream is null");
		}
		Properties properties = null;
		try {
			String content = StringUtils.inputStreamToRightString(is, charset);
			properties = loadProperties(content);
		} catch (IOException ioe) {
			throw new PropertiesLoadFailedException("When load properties from inputStream", ioe);
		}
		return properties;
	}
	
	public static Properties loadProperties(String content) throws PropertiesLoadFailedException{
		Properties properties = new Properties();
		if(StringUtils.isNullString(content)){
			return properties;
		}
		ByteArrayInputStream sbis = new ByteArrayInputStream(content.getBytes());
		try {
			properties.load(sbis);
		} catch (IOException e) {
			throw new PropertiesLoadFailedException("When load properties from inputStream loadProperties(String content)", e);
		}finally{
			try{
				sbis.close();
			}catch(Exception e){/*will never be here*/}
		}
		return properties;
	}
}
